-- @Author: baidwwy
-- @Date:   2018-04-18 09:33:54
-- @Last Modified by:   baidwwy
-- @Last Modified time: 2018-05-16 23:05:07
ffi.cdef[[
    void* BeginUpdateResourceA(const char *,bool);
    bool UpdateResourceA(void*,const char *,const char *,int,const char *,int);
    bool EndUpdateResourceA(void*,bool);
]]
版本 = '1.0b2'
require("ffi函数")
require("gge函数")
文件列表 = {}
function 查找文件(目录,筛选)
    local file = ffi.new("_finddata32_t")
    local HANDLE = ffi.C._findfirst32(目录..'/*.*',file)
    if HANDLE ~= -1 then
        repeat
            local name = ffi.string(file.name)
            if name ~= '.' and name ~='..' then
                if bit.band(file.attrib,16) == 16 then
                    查找文件(目录..'/'..name,筛选)
                elseif name:match("%w+$")==筛选 then--全名或者扩展名
                    table.insert(文件列表, 目录.."/"..name)
                end
            end
        until ffi.C._findnext32(HANDLE,file)==-1
    end
    ffi.C._findclose(HANDLE)
end
cmd = __gge.command
print ("GGELUA 编译器 "..版本)
if #cmd<2 then goto ERRCMD; end
if __gge.isdebug then--编译自己
    项目路径 = cmd[#cmd]:gsub('\\','/')
    引擎路径 = __gge.runpath..'/'
    编译模式 = 'ggeserver'
else
    项目路径 = cmd[#cmd]:gsub('\\','/')
    引擎路径 = __gge.runpath..'/../'
    编译模式 = cmd[#cmd-1]
end
编译目录 = 项目路径.."/compile/"
os.mkdir(编译目录)
if 编译模式 == 'ggebc' then goto GGEBC; end--支持库
--===============================================================
do
    local 索引列表,t = {}
    t = os.clock()
    查找文件(引擎路径..'/脚本','lua')
    查找文件(项目路径,'lua')
print(string.format('--------------------------------------------------\n查找脚本用时 %ss', os.clock()-t))
    --编译
    t = os.clock()
    local offset = ffi.sizeof('bdf_head')
    for i,v in ipairs(文件列表) do
        local path = v:gsub(项目路径,'.'):gsub(引擎路径,'.'):lower() --:gsub('\\','/')
        local str = __gge.utf8toansi(__gge.readfile(v))
        local fun,err = loadstring(str, path)
        if fun then
            print('  编译->"'..path..'"',__gge.adler32(path))
            文件列表[i] = string.dump(fun)
            table.insert(索引列表, {
                crc32  = __gge.adler32(path);
                offset = offset;
                len    = #文件列表[i];
                xor    = {
                    math.random(1, 255);
                    math.random(1, 255);
                    math.random(1, 255);
                    math.random(1, 255)
                };
            })
            offset = offset+#文件列表[i]
        else
            print('读入脚本失败',v)
            print(err)
            os.exit(1)
        end
    end
print(string.format('--------------------------------------------------\n编译脚本"%s"个共用时 %ss',#文件列表 ,os.clock()-t))
    os.copyfile(引擎路径..编译模式..'.exe',编译目录..'temp.exe')
    --打包
    local head = ffi.string(ffi.new('bdf_head',{
        flag   = 4540231;
        total  = #文件列表;
        offset = offset;
    }),ffi.sizeof('bdf_head'))
    local list = ffi.string(ffi.new('bdf_list[?]',#文件列表,索引列表),
        ffi.sizeof('bdf_list')*#文件列表)
    local DATA = head..table.concat(文件列表)..list
    --写EXE
    local handle = ffi.C.BeginUpdateResourceA(编译目录.."temp.exe",false)
    if handle~=nil then
        if ffi.C.UpdateResourceA(handle,'GGELUA','DATA',0,DATA,#DATA) then
            if ffi.C.EndUpdateResourceA(handle,false) then
                if 编译模式 == 'ggegame' then
                    os.copyfile(引擎路径..'lua51.dll',编译目录..'lua51.dll')
                    os.copyfile(引擎路径..'Galaxy2d.dll',编译目录..'Galaxy2d.dll')
                elseif 编译模式 == 'ggeserver' then
                    os.copyfile(引擎路径..'lua51.dll',编译目录..'lua51.dll')
                    os.copyfile(引擎路径..'HPSocket.dll',编译目录..'HPSocket.dll')
                    --os.copyfile(引擎路径..'Logger.dll',编译目录..'Logger.dll')
                end
                local r = os.remove(编译目录..编译模式..'.exe')
                if r==nil or r then
                    os.rename(编译目录..'temp.exe', 编译目录..编译模式..'.exe')
                    print('打包完成。')
                else
                    print('文件占用，打包失败。')
                end
                return
            end
        end
    end
    print("--------------------------------------------------\n写入EXE失败。")
    os.exit(2)
end
::GGEBC::
do
    查找文件(项目路径..'/脚本','lua')
    local head = "local GGELUA = __gge.dozlibbase64[[\n%s\n]]\n"
    local pat = string.format("(%s)", string.rep(".", 100))
    for i,v in ipairs(文件列表) do
        if v:sub(-9)~='_接口.lua' then
            local name = string.match(v, ".+/([^/]*%.%w+)$")
            local 接口 = string.gsub(v, '.lua','_接口.lua')
            if os.access(接口) then
                local str = __gge.utf8toansi(__gge.readfile(v))
                local fun,err = loadstring(str)


                if fun then
                    local dump = string.dump(fun)
                    local base64 = __gge.enbase64(__gge.compress(dump))
                    base64 = base64:gsub(pat,'%1\n')
                    base64 = head:format(base64)
                    base64 = __gge.ansitoutf8(base64)..__gge.readfile(接口)
                    __gge.writefile(编译目录..name,base64)
                    print('  生成->"'..编译目录..name..'"')
                else
                    print('读入脚本失败',v)
                    print(err)
                    os.exit(1)
                end
            else
                print('接口文件不存在:"'..接口..'"')
                os.exit(2)
            end
        end
    end
    print('完成。')
    return
end
::ERRCMD::
print('参数错误')
print('ggebuild.exe 模式 目录')
os.execute('pause')